# -arch指定目标GPU的指令集架构
# sm_80对应Ampere架构的A100
# sm_86对应Ampere架构的A10/A30/RTX30xx
# sm_89对应Ada Lovelace的RTX40xx
# 详细列表见https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/

# 沐曦的GPU上，直接使用make_maca进行编译。

# nvcc -arch=sm_86 -o 0_reduction_global.exe 0_reduction_global.cu
# nvcc -arch=sm_86 -o 0_reduction_shared.exe 0_reduction_shared.cu
# nvcc -arch=sm_86 -o 1_reduction_no_divergence.exe 1_reduction_no_divergence.cu
# nvcc -arch=sm_86 -o 2_reduction_no_bank_conflict.exe 2_reduction_no_bank_conflict.cu
# nvcc -arch=sm_86 -o 3_reduction_add_load.exe 3_reduction_add_load.cu
# nvcc -arch=sm_86 -o 4_reduction_multiple_add.exe 4_reduction_multiple_add.cu
# nvcc -arch=sm_86 -o 5_reduction_shuffle.exe 5_reduction_shuffle.cu

# 定义CUDA架构变量，这里指定为sm_80（适用于NVIDIA Ampere架构）
ARCH := sm_80

# make命令在没有指定目标时会执行第一个目标，通常命名为"all"。
# 这里的all依赖于所有的.exe文件，这意味着执行make时会构建所有的可执行文件。
all : 0_reduction_global.exe 0_reduction_shared.exe 1_reduction_no_divergence.exe 2_reduction_no_bank_conflict.exe 3_reduction_add_load.exe 4_reduction_multiple_add.exe 5_reduction_shuffle.exe

# 以下是各个目标文件的构建规则
# 依赖关系：每个.exe文件都依赖于对应的.cu源文件
0_reduction_global.exe : 0_reduction_global.cu
	nvcc -arch=$(ARCH) -o 0_reduction_global.exe 0_reduction_global.cu

# $@ 表示目标文件名（等号左边）
# $^ 表示所有依赖文件（等号右边）
# 构建使用共享内存的reduction版本
0_reduction_shared.exe : 0_reduction_shared.cu
	nvcc -arch=$(ARCH) -o $@ $^

# 构建消除分支发散的reduction版本
1_reduction_no_divergence.exe : 1_reduction_no_divergence.cu
	nvcc -arch=$(ARCH) -o $@ $^

# 构建消除bank冲突的reduction版本
2_reduction_no_bank_conflict.exe : 2_reduction_no_bank_conflict.cu
	nvcc -arch=$(ARCH) -o $@ $^

# 构建优化加载的reduction版本
3_reduction_add_load.exe : 3_reduction_add_load.cu
	nvcc -arch=$(ARCH) -o $@ $^

# 构建多重归约的reduction版本
4_reduction_multiple_add.exe : 4_reduction_multiple_add.cu
	nvcc -arch=$(ARCH) -o $@ $^

# 构建使用shuffle指令的reduction版本
5_reduction_shuffle.exe : 5_reduction_shuffle.cu
	nvcc -arch=$(ARCH) -o $@ $^

# 清理目标，删除所有生成的可执行文件
# 通配符使用。这里用到了*.exe这样的通配符，它会匹配所有以.exe结尾的文件。通配符在文件匹配时非常有用。
clean :
	rm -rf *.exe